////////////////////////////////////////////////////////////////////////
//  File Name	:	"CBase.cpp"
//	Author Name	:	Brandon Layton (BL)
//	Purpose		:	to encapsulate all related data and functionality for
//					our game objects
////////////////////////////////////////////////////////////////////////
#include "../headers/Base.h"

#include "../Systems/Direct3D.h"
#include "../headers/Game.h"

unsigned int CBase::m_uiNextID = 0;

CBase::CBase()
{

	m_bCleanUpTexture = false;

	SetPosition(vector2D());
	SetVelocity(vector2D());

	SetImageID(-1);

	m_uiRefCount = 1; //Start with a ref to yourself
	
	m_nType =	OBJ_BASE;
	
	m_vAnchorPoint = vector2D(0, 0);

	m_fMaxSpeed = 0.0f;

	m_vHeading = vector2D(1.0f, 0.0f);
	
	m_bCanCollide = false;

	m_nWidth = 0;
	m_nHeight = 0;

	m_uiLayer = 2; //Default to player layer

	m_fDamage = 0.0f;

	m_bTagged = false;

	m_fBoundingRadius = 0.0f;

	m_bObstacle = false;

	m_bIsEnemy = false;

	m_bDrawBasedOnSize = false;

	m_nImageID = -1;

	ZeroMemory(&m_rCollisionRect, sizeof(RECTF));
	m_uiID = CBase::m_uiNextID;
	CBase::m_uiNextID++;
}

CBase::~CBase()
{
	if(m_bCleanUpTexture)
		CTextureManager::GetInstance()->UnloadTexture(m_nImageID);
}


void CBase::Update(float dt, bool getInput)
{
	SetPosX( GetPosX() + GetVelX() * dt);
	SetPosY( GetPosY() + GetVelY() * dt);

	if(GetVelocity().Length() > 0.0f)
		SetHeading(Vector2DNormalize(GetVelocity()));
}

void CBase::Render(vector2D & vCamera)
{
	
	if(m_nImageID == -1)
		return;

	//If the object is off the screen then just return and don't draw
	RECTF rect = GetDrawRect();
	if(rect.right - vCamera.fX < 0.0f || rect.left - vCamera.fX > CGame::GetInstance()->GetScreenWidth())
		return;
	if(rect.bottom - vCamera.fY < 0.0f || rect.top - vCamera.fY > CGame::GetInstance()->GetScreenHeight())
		return;

	//Draw the image, taking in account for camera position and anchor point position
	CTextureManager::GetInstance()->Draw( GetImageID(), rect.left - vCamera.fX, rect.top - vCamera.fY, m_vAnchorPoint.fX, m_vAnchorPoint.fY, 1.0f, 1.0f, &GetImageRect(), (m_bDrawBasedOnSize ? &vector2D((float)m_nWidth, (float)m_nHeight) : NULL));


#if _DEBUG
	//if(m_bObstacle)
	//{
	//	rect = GetCollisionRect();
	//	if(rect.right <= 0)
	//		return;
	//	RECT r = {(LONG)(rect.left - vCamera.fX), (LONG)(rect.top - vCamera.fY), (LONG)(rect.right - vCamera.fX),(LONG) (rect.bottom - vCamera.fY) };
	//	CDirect3D::GetInstance()->DrawRect(r, 255, 0, 0);


	//	CDirect3D::GetInstance()->DrawX(GetCenter() - vCamera, RED, (int)GetBoundingRadius());
	//}
	//else
	//{	
	//	rect = GetCollisionRect();
	//	if(rect.right <= 0)
	//		return;
	//	RECT r = {(LONG)(rect.left - vCamera.fX), (LONG)(rect.top - vCamera.fY), (LONG)(rect.right - vCamera.fX),(LONG) (rect.bottom - vCamera.fY) };
	//	CDirect3D::GetInstance()->DrawRect(r, 255, 0, 0);

	//	CDirect3D::GetInstance()->DrawX(GetCenter() - vCamera, RED, (int)GetBoundingRadius());
	//}
#endif
}

void CBase::AddRef()
{
	m_uiRefCount++;
}

void CBase::Release()
{
	m_uiRefCount--;
	
	if(m_uiRefCount == 0)
	{
		delete this;
	}
}


////////////////////////////////////////////////
//	GetDrawRect:
//	Returns a rectangle the object will be drawn
//  on the screen based on the objects size
//	translated into world coordinates, taking into
//	consideration any anchoring
////////////////////////////////////////////////

RECTF CBase::GetDrawRect(void) const
{
	RECTF rect;

	rect.left = GetPosX() - GetAnchorPoint().fX;
	rect.top = GetPosY() - GetAnchorPoint().fY;
	rect.right = rect.left + m_nWidth;	
	rect.bottom = rect.top + m_nHeight;

	return rect;
}

////////////////////////////////////////////////
//	GetCollisionRect:
//	Get the size of the collision rectangle
//  and factor in the objects position to
//  return a rectangle in world space
////////////////////////////////////////////////

RECTF CBase::GetCollisionRect(void) const
{
	RECTF rect = m_rCollisionRect;
	

	rect.left += GetPosX();
	rect.top += GetPosY();
	rect.right += GetPosX();
	rect.bottom += GetPosY();
	
	return rect;
}

////////////////////////////////////////////////
//	SetCollisionRect:
//	Set the size of the collision rectangle
//  and Calculate the new Bounding Sphere
////////////////////////////////////////////////

void CBase::SetCollisionRect(RECTF rect)
{
	m_rCollisionRect = rect;

	//Calculate a new bounding radius with the new collision rect
	m_fBoundingRadius = Max<float>(rect.right - rect.left, rect.bottom - rect.top);
	m_fBoundingRadius *= 0.5f;

	m_vCenter.fX = (float)((rect.right + rect.left) / 2.0f);
	m_vCenter.fY = (float)((rect.bottom + rect.top) / 2.0f);
}

bool RectsIntersect(RECTF & s1, RECTF & s2)
{
	if(PointInRect(s1.left, s1.top, s2) || PointInRect(s2.left, s2.top, s1))
		return true;
	if(PointInRect(s1.right, s1.top, s2) || PointInRect(s2.right, s2.top, s1))
		return true;
	if(PointInRect(s1.left, s1.bottom, s2) || PointInRect(s2.left, s2.bottom, s1))
		return true;
	if(PointInRect(s1.right, s1.bottom, s2) || PointInRect(s2.right, s2.bottom, s1))
		return true;

	return false;
}
bool CBase::CheckCollision(CBase* pBase)
{
	if(GetCanCollide() == false)
		return false;

	RECTF s1 = pBase->GetCollisionRect();
	RECTF s2 = GetCollisionRect();

	if(RectsIntersect(s1, s2))
	{
		return true;
		////if(pBase->GetIsPerPixel() || GetIsPerPixel())
		//if(pBase->GetImageID() != -1 || GetImageID() != -1)
		//	return CTextureManager::GetInstance()->IntersectPixels(s1, pBase->GetImageID(), s2, GetImageID());
		//else
		//	return true;
		
	}
	
	return false;
}

void CBase::SetLayer(unsigned int layer) 
{ 
	m_uiLayer = layer; 
	
	if(layer != 2)
		SetCanCollide(false);
}